<template>
  <div id="nav-box">
    <div class="link-box">
      <router-link to="/">
        <div class="head-logo">
          <img src="@/assets/icon/we-roast-logo.png" alt="">
        </div>
      </router-link>
      <ul id="nav-item">
        <li class="slide1"></li>
        <li class="slide2"></li>
        <li :class="{'active' : activeNav === index}" v-for="(item, index) in navBoxData" :key="item.key">
          <a @click="() => $router.push(item.path)">{{ item.label }}</a>
        </li>
      </ul>
    </div>
    <div class="right-box">
      <div class="search-box" :class="{'search-open' : inputting}">
        <input class="search-input" v-model="page.keyword" @keydown.enter="searchManga"/>
        <a class="search-btn" href="#" @click="searchManga">
          <i :class="{'el-icon-search' : !onSearching, 'el-icon-loading': onSearching}"/>
        </a>
        <div class="search-data animate__animated animate__bounceInDown" v-if="showSearchData" @scroll.passive="handleScroll">
          <div v-if="searchData.length === 0" class="search-data-noItem">
            未找到相关漫画
          </div>
          <div class="search-data-item"
               @click="toEpPage(item.mangaId)"
               v-for="(item, index) in searchData" :key="index">
            <img loading="lazy" decoding="async" :src="item.thumbCoverUrl ? item.thumbCoverUrl : item.coverUrl" alt="">
            <div class="search-data-info">
              <div class="title text-ellipsis" v-html="highlightKeyword(item.name, page.keyword)"></div>
              <div class="author text-ellipsis" v-html="highlightKeyword(item.author, page.keyword)"></div>
              <div class="cnTeam text-ellipsis" v-html="highlightKeyword(item.cnTeam, page.keyword)"></div>
              <div class="update ">更新至 {{ item.lastEpName }}</div>
            </div>
          </div>
        </div>
      </div>
      <div class="head-power">
        <download-box/>
        <span class="divider"></span>
        <login-box v-if="!isLogin" @flashNavBox="init"/>
        <info-box v-if="isLogin" :userName="userName" @flashNavBox="init"/>
      </div>
    </div>
  </div>
</template>

<script>
import loginBox from "@/components/login/loginBox.vue";
import infoBox from "@/components/login/InfoBox.vue"
import {getToken} from "@/util/auth";
import $ from 'jquery';
import {searchManga} from "@/api/mgApi";
import {highlightKeyword} from "@/util/strUtil";
import DownloadBox from "@/components/download/downloadBox.vue";

export default {
  name: "navBox",
  components: {DownloadBox, loginBox, infoBox},
  data() {
    return {
      activeNav: 0,
      isLogin: false,
      userName: '',
      navBoxData: [
        {
          key: 1,
          label: 'HOME',
          path: '/mgHome',
          needLogin: false
        },
        {
          key: 2,
          label: 'COOKE',
          path: '/mineMg',
          needLogin: true
        },
        {
          key: 3,
          label: 'TEAM',
          path: '/cnTeam',
          needLogin: true
        }
      ],
      isScrolling: false, // 用于节流，防止滚动事件频繁触发
      searchData: [],
      onSearching: false,
      showSearchData: false,
      page: {
        keyword: '',
        page: 1,
        size: 5
      },
      pages: 0
    }
  },
  computed: {
    currentItemIndex() {
      return this.navBoxData.findIndex(item => item.path === this.$route.path);
    },
    inputting() {
      return this.page.keyword.length > 0;
    }
  },
  methods: {
    highlightKeyword,
    init() {
      this.isLogin = false;
      const token = getToken();
      if (token !== undefined && token !== null && token !== '') {
        this.isLogin = true;
      }
      this.userName = localStorage.getItem('wr-user')
      this.activeNav = Number(localStorage.getItem('activeNav'))
    },
    /**
     * 初始化导航栏动画
     */
    initiateNavAnimations() {
      let navItem = $("#nav-item a");

      navItem.on("click", function () {
        let position = $(this).parent().position();
        let width = $(this).parent().width();
        $("#nav-item .slide1").css({opacity: 1, left: +position.left, width: width});
      });

      navItem.on("mouseover", function () {
        let position = $(this).parent().position();
        let width = $(this).parent().width();
        $("#nav-item .slide2").css({opacity: 1, left: +position.left, width: width}).addClass("squeeze")
      });

      navItem.on("mouseout", function () {
        $("#nav-item .slide2").css({opacity: 0}).removeClass("squeeze")
      });
      this.computeSlide1Position()
    },
    /**
     * 计算滑块位置
     */
    computeSlide1Position() {
      let currentNavIndex = this.currentItemIndex;
      if (currentNavIndex !== -1) {
        // 高亮滑块所在的导航栏
        this.activeNav = currentNavIndex;
        localStorage.setItem('activeNav', this.activeNav)
      } else {
        currentNavIndex = this.activeNav
      }
      let currentWidth = $(`#nav-item li:nth-of-type(${currentNavIndex + 3}) a`).parent("li").width();
      let current = $(`li:nth-of-type(${currentNavIndex + 3}) a`).position();
      $("#nav-item .slide1").css({left: +current.left, width: currentWidth});
    },
    /**
     * 初始化搜索框
     */
    initSearchBox() {
      this.page = {
        page: 1,
        size: 5,
        keyword: ''
      }
      this.searchData = []
      this.onSearching = false
      this.showSearchData = false
      this.pages = 0
    },
    /**
     * 查询漫画
     */
    searchManga() {
      let keyword = this.page.keyword;
      if (keyword !== '' && !this.onSearching) {
        this.onSearching = true
        // 重置分页
        this.page.page = 1
        this.page.size = 5
        this.pages = 0
        searchManga(this.page).then(res => {
          this.searchData = res.data.records
          this.pages = res.data.pages
          this.showSearchData = true
        }).finally(() => {
          setTimeout(() => {
            this.onSearching = false
          }, 500)
        })
      }
    },
    /**
     * 滚动触底事件
     */
    async handleScroll(event) {
      // 使用节流来优化性能
      if (this.isScrolling) return;
      this.isScrolling = true;
      await this.$nextTick();
      this.isScrolling = false;

      const container = event.target;
      // 判断是否滚动到底部（滚动高度等于容器高度 + 滚动条位置）
      if (container.scrollHeight - container.scrollTop === container.clientHeight) {
        // 在这里执行加载更多数据的逻辑
        this.loadMoreData();
      }
    },
    /**
     * 加载更多数据
     */
    loadMoreData() {
      // 如果已经加载完所有数据，则不执行加载更多
      if (this.pages <= this.page.page || this.onSearching) {
        return;
      }
      this.onSearching = true
      this.page.page++
      // 发起请求获取更多数据
      searchManga(this.page).then(res => {
        this.searchData.push(...res.data.records)
      }).finally(() => {
        setTimeout(() => {
          this.onSearching = false
        }, 500)
      })
    },
    /**
     * 点击其他区域时隐藏搜索结果
     */
    handleSearchOutsideClick(event) {
      // 判断点击的目标元素是否是你希望监听的元素之外
      const clickedComponent = event.target.closest('.search-box');
      if (!clickedComponent) {
        // 如果点击的不是你的组件或其子元素，执行相应操作
        this.initSearchBox()
      }
    },
    toEpPage(id) {
      this.$router.push("/mgEp?id=" + id)
      this.initSearchBox()
    }
  },
  mounted() {
    this.init()
    this.initiateNavAnimations()
    this.initSearchBox()
    // 注册点击事件监听器
    document.addEventListener('click', this.handleSearchOutsideClick);
  },
  beforeUnmount() {
    // 组件卸载前记得移除事件监听器，避免内存泄漏
    document.removeEventListener('click', this.handleSearchOutsideClick);
  },
  watch: {
    $route() {
      this.computeSlide1Position()
    },
    'page.keyword'(newVal, oldVal) {
      // 当输入框由有值变为空时，初始化搜索框
      if (newVal === '' && oldVal !== '') {
        this.initSearchBox()
      }
    }
  }
}
</script>

<style scoped lang="scss">
#nav-box {
  width: 100%;
  background-color: rgba(255, 255, 255, 0.8);
  box-shadow: 0 0 8px rgba(0, 0, 0, 0.2);
  display: flex;
  justify-content: space-between;
  height: 70px;
  padding: 0 20vh 0 15vh;

  .link-box {
    display: flex;
    align-items: center;
    position: relative;

    .head-logo {
      position: absolute;
      left: -40px;
      top: 0;
      display: flex;
      justify-content: center;
      align-items: center;
      width: 90px;
      height: 90px;
      border-radius: 50%;
      background-color: #FFFFFF;
      box-shadow: 0 6px 3px -3px rgba(0, 0, 0, 0.2);

      & img {
        height: 90%;
        width: 90%;
        object-fit: fill
      }
    }
  }

  #nav-item {
    color: var(--theme-color);
    display: flex;
    position: relative;
    border: none;
    border-radius: 10em;
    list-style: none;
    padding: 10px;
    margin-left: 8vh;

    .active {
      color: #FFFFFF;
    }

    & li a {
      position: relative;
      padding: 16px 30px;
      display: inline-block;
      font: 17px 'joke-font';
      font-family: 'joke-font', sans-serif !important;
      cursor: pointer;
      z-index: 3;
    }

    .slide1, .slide2 {
      position: absolute;
      display: inline-block;
      height: 48px;
      border-radius: 5px;
      transition: all 0.6s cubic-bezier(0.23, 1, 0.32, 1.05);
    }

    .slide1 {
      background-color: var(--theme-color);
      z-index: 2;
    }

    .slide2 {
      background-color: rgba(47, 120, 177, 0.54);
      z-index: 1;
      box-shadow: 0 0 20px #ffffffaa inset;
    }

    .squeeze {
      transform: scale(0.9);
    }
  }

  .right-box {
    display: flex;
    align-items: center;

    .search-box {
      height: 40px;
      border: 1px solid #dcdfe6;
      border-radius: 40px;
      display: flex;
      align-items: center;
      position: relative;

      .search-input {
        border: none;
        background: none;
        outline: none;
        float: left;
        width: 0;
        padding: 0;
        transition: 0.4s;
        line-height: 40px;
      }

      .search-btn {
        color: var(--theme-color);
        font-weight: bold;
        float: right;
        width: 40px;
        height: 40px;
        border-radius: 50%;
        display: flex;
        justify-content: center;
        align-items: center;
        transition: 0.4s;
      }

      &:hover {
        border: 1px solid var(--theme-color);
        padding-left: 10px;
      }

      &:hover > .search-input {
        width: 200px;
        padding: 0 10px;
      }

      &:hover > .search-btn {
        transform: scale(0.8);
        background: var(--theme-color);
        color: #FFFFFF;
      }

      .search-data {
        position: absolute;
        top: 46px;
        left: -95px;
        width: 345px;
        max-height: 400px;
        overflow-y: auto;
        border: 1px solid var(--theme-color);
        border-radius: 5px;
        background: #FFFFFF;
        box-shadow: 8px 17px 7px rgba(0, 0, 0, 0.3);
        z-index: 10;

        /* 滚动条背景 */
        &::-webkit-scrollbar {
          display: none;
        }

        .search-data-noItem {
          height: 50px;
          display: flex;
          justify-content: center;
          align-items: center;
          color: var(--theme-color);
          opacity: 0.6;
          font-weight: bold;
        }

        .search-data-item {
          height: 110px;
          display: flex;
          justify-content: flex-start;
          align-items: center;
          padding: 0 10px;
          transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1.05);
          cursor: pointer;

          &:hover {
            background: rgba(20, 50, 74, 0.2);
          }

          img {
            width: 75px;
            height: 95px;
            object-fit: fill;
          }

          .search-data-info {
            display: flex;
            flex-direction: column;
            justify-content: flex-start;
            padding: 5px 0 0 10px;
            width: calc(100% - 90px);
            height: 100%;
            color: var(--theme-color);

            .title {
              font-weight: bold;
              font-size: 20px;
            }
            .author {
              font-size: 12px;
              opacity: 0.8;
            }
            .cnTeam {
              margin-top: auto;
              font-size: 14px;
            }
            .update {
              padding-bottom: 10px;
              font-size: 12px;
            }
          }

        }
      }
    }

    .search-open {
      border: 1px solid var(--theme-color);
      padding-left: 10px;

      .search-input {
        width: 200px;
        padding: 0 10px;
      }

      .search-btn {
        transform: scale(0.8);
        background: var(--theme-color);
        color: #FFFFFF;
      }
    }

  }

  .head-power {
    padding-left: 10px;
    display: flex;
    align-items: center;

    .divider {
      display: flex;
      border: 1px solid #f4f6f6;
      box-sizing: border-box;
      height: 25px;
      margin: 0 5px;
    }
  }
}

</style>